package cn.edu.buaa.sei.jdat.vt;

import java.awt.Dialog.ModalityType;

import javax.swing.JDialog;

import cn.edu.buaa.sei.jdat.JarController;
import cn.edu.buaa.sei.jdat.model.Jar;
import cn.edu.buaa.sei.jdat.search.SearchController;
import cn.edu.buaa.sei.jdat.vt.res.Resources;
import cn.edu.buaa.sei.jdat.vt.widgets.Button;
import cn.edu.buaa.sei.jdat.vt.widgets.JarListView;
import cn.edu.buaa.sei.jdat.vt.widgets.TabButton;

import com.cocotingo.snail.GraphicsX;
import com.cocotingo.snail.MouseEvent;
import com.cocotingo.snail.View;
import com.cocotingo.snail.dispatcher.Dispatcher;

public class MainView extends View {
	
	public static abstract class Tab extends View {
		
		private final MainView owner;

		public Tab(MainView owner) {
			super(0, 0, 0, 0);
			this.owner = owner;
			setHidden(true);
			setPaintingEnabled(false);
		}
		
		public MainView getOwner() {
			return owner;
		}
		
		public boolean isActivated() {
			return !isHidden();
		}
		
		@Override
		public View setHidden(boolean hidden) {
			if (!hidden) {
				layout();
			}
			return super.setHidden(hidden);
		}
		
		@Override
		public View setSize(int width, int height) {
			super.setSize(width, height);
			if (isActivated()) {
				layout();
			}
			return this;
		}
		
		protected abstract void activated();
		protected abstract void deactivated();
		protected abstract void layout();
	}
	
	// controllers
	private final JarController jarController;
	private final SearchController searchController;
	
	// controls
	private final JarListView jarListView;
	private final Button btnImportJars, btnEditJarList;
	private final TabButton tabMain;
	private final NavigateView navigateView;
	private final DependencyView dependencyView;
	private final SearchView searchView;
	
	// layout vars
	private int margin = 8;
	private int jarlistWidth = 300;
	private int buttonHeight = 40;

	public MainView() {
		super(0, 0, 0, 0);
		setKeyboardFocusable(true);
		
		// define controls
		jarListView = new JarListView(0, 0, 0, 0) {
			@Override
			protected void selectedItemChanged(Item item) {
				if (item != null) {
					final Jar jar = jarController.getJar(item.getIndex());
					if (navigateView.isActivated()) {
						navigateView.showJar(jar);
					}
				} else {
					navigateView.clear();
				}
			}
		};
		
		btnImportJars = new Button(0, 0, 0, 0) {
			{
				setText("Import Jars");
			}
			@Override
			protected void postMouseClicked(MouseEvent e) {
				e.handle();
				btnImportJarClicked();
			}
		};
		
		btnEditJarList = new Button(0, 0, 0, 0) {
			{
				setText("Edit");
			}
			@Override
			protected void postMouseClicked(MouseEvent e) {
				e.handle();
				btnEditJarListClicked();
			}
		};
		
		tabMain = new TabButton(0, 0, 0, 0) {
			{
				setTexts(new String[] {"Navigate", "Dependency Graph", "Search"});
			}
			@Override
			protected void selectedTabChanged(int selectedIndex) {
				MainView.this.selectedTabChanged(selectedIndex);
			}
		};
		
		navigateView = new NavigateView(this) {
		};
		dependencyView = new DependencyView(this) {
		};
		searchView = new SearchView(this) {
		};
		
		// add to root view
		addSubview(jarListView);
		addSubview(btnImportJars);
		addSubview(btnEditJarList);
		addSubview(tabMain);
		addSubview(navigateView);
		addSubview(dependencyView);
		addSubview(searchView);
		tabMain.setSelectedIndex(0);
		layout();
		
		// create controller
		jarController = new JarController() {

			@Override
			protected void importJarStarted(final Jar jar) {
				Dispatcher.executeAndWaitAndSyncWithGUI(new Runnable() {
					@Override
					public void run() {
						JarListView.Item item = new JarListView.Item(jarListView, jar.getURI());
						jarListView.getContentView().addSubview(item);
						jarListView.layout();
					}
				});
			}

			@Override
			protected void importJarFinished(Jar jar) {
				// TODO Auto-generated method stub
			}

			@Override
			protected void removeJarStarted(Jar jar) {
				// TODO Auto-generated method stub
				
			}

			@Override
			protected void removeJarFinished(Jar jar) {
				// TODO Auto-generated method stub
				
			}

			@Override
			protected void jarStateChanged(final Jar jar, final int state) {
				Dispatcher.executeAndWaitAndSyncWithGUI(new Runnable() {
					@Override
					public void run() {
						final JarListView.Item item = jarListView.getItem(jarController.indexOfJar(jar));
						switch (state) {
						case Jar.INITIALIZED:
							item.setName("");
							item.setStatus("");
							item.setDetailText(jar.getURI());
							break;
						case Jar.LOADING:
							item.setStatus("Downloading");
							break;
						case Jar.ERROR:
							item.setStatus("Error");
							break;
						case Jar.PARSING:
							item.setName(jar.getName());
							item.setStatus("Analysing");
							break;
						case Jar.READY:
							item.setStatus("");
							item.showDetailText();
							break;
						}
					}
				});
			}
			
		};
		
		searchController = new SearchController();
	}
	
	private void layout() {
		btnEditJarList.setSize(80, buttonHeight);
		btnImportJars.setFrame(margin, margin, jarlistWidth - margin - btnEditJarList.getWidth(), buttonHeight);
		btnEditJarList.setPosition(margin * 2 + btnImportJars.getWidth(), margin);
		
		jarListView.setPosition(margin, margin * 2 + btnImportJars.getHeight());
		jarListView.setWidth(jarlistWidth);
		jarListView.setBottom(margin);
		
		tabMain.setSize(Math.max((getWidth() - jarlistWidth - margin * 3) * 7 / 10, 600), buttonHeight);
		tabMain.setPosition(margin + jarlistWidth + (jarListView.getRight() - tabMain.getWidth()) / 2, margin);
		
		navigateView.setPosition(jarListView.getWidth() + 2 * margin, tabMain.getHeight() + 2 * margin);
		navigateView.setBottom(margin);
		navigateView.setRight(margin);
		dependencyView.setPosition(navigateView.getPosition());
		dependencyView.setSize(navigateView.getSize());
		searchView.setPosition(navigateView.getPosition());
		searchView.setSize(navigateView.getSize());
		
		setNeedsRepaint();
	}
	
	@Override
	protected void postMousePressed(MouseEvent e) {
		resignKeyboardFocus();
	}

	@Override
	protected void repaintView(GraphicsX g) {
		Resources.fillBackground(g, getWidth(), getHeight());
		final int left = jarListView.getWidth() + margin * 2;
		final int top = buttonHeight + margin * 2;
		g.translate(left, top);
		g.drawStrechableImage(Resources.IMG_DEPTH_BACKGROUND, getWidth() - left - margin, getHeight() - top - margin);
		g.translate(-left, -top);
	}
	
	@Override
	public View setSize(int width, int height) {
		super.setSize(width, height);
		if (jarListView != null) {
			layout();
		}
		return this;
	}
	
	public JarController getJarController() {
		return jarController;
	}
	
	public SearchController getSearchController() {
		return searchController;
	}
	
	public JarListView getJarListView() {
		return jarListView;
	}
	
	//// delegates ////
	
	private void btnImportJarClicked() {
		try {
			ImportDialog dialog = new ImportDialog(this);
			dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
			dialog.setModalityType(ModalityType.APPLICATION_MODAL);
			dialog.setVisible(true);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void btnEditJarListClicked() {
		// TODO
	}
	
	private void selectedTabChanged(int index) {
		if (!navigateView.isHidden()) {
			navigateView.setHidden(true);
			navigateView.deactivated();
		}
		if (!dependencyView.isHidden()) {
			dependencyView.setHidden(true);
			dependencyView.deactivated();
		}
		if (!searchView.isHidden()) {
			searchView.setHidden(true);
			searchView.deactivated();
		}
		switch (index) {
		case 0:
			navigateView.activated();
			navigateView.setHidden(false);
			break;
		case 1:
			dependencyView.activated();
			dependencyView.setHidden(false);
			break;
		case 2:
			searchView.activated();
			searchView.setHidden(false);
			break;
		}
	}
	
}
